package dxt.learn.example.demo.hotplugging.config;

import dxt.learn.example.demo.hotplugging.annotation.HotPluggingMethod;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.LinkedList;
import java.util.List;

public class HostPluggingProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        Class clazz = bean.getClass();
        for (Method method : findAllMethod(clazz)) {
            processMethod(bean, beanName, method);
        }
        return bean;

    }

    protected void processMethod(Object bean, String beanName, Method method) {
        HotPluggingMethod hotPluggingMethod = AnnotationUtils.getAnnotation(method, HotPluggingMethod.class);
        if (hotPluggingMethod == null) {
            return;
        }
        String switchKey = hotPluggingMethod.switchKey();//控制key
        if(StringUtils.isEmpty(switchKey)){
            Parameter[] parameters = method.getParameters();
            String appendParamName = "";
            for (Parameter parameter : parameters) {
                appendParamName+=parameter.getType().getName();
            }
            switchKey = bean.getClass().getName()+method.getName()+method.getParameterCount()+appendParamName;
        }
        System.out.println(switchKey);

    }


    private List<Method> findAllMethod(Class clazz) {
        final List<Method> res = new LinkedList<>();
        ReflectionUtils.doWithMethods(clazz, (method) -> res.add(method));
        return res;
    }


    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}
